home *** CD-ROM | disk | FTP | other *** search
/ HAM Radio 1997 / HAM Radio 1997.iso / vcls / resizer / resizer.pas < prev    next >
Pascal/Delphi Source File  |  1996-04-08  |  9KB  |  281 lines

  1. {*
  2.  * NO THIS IS NOT PERFECT. IF YOU DON'T LIKE IT, DON'T USE IT!
  3.  *
  4.  * This is a simple VC that resizes all the controls on a form.
  5.  *
  6.  * All you have to do is place the RESIZER component on your form,
  7.  * set the 'OnSized' event for the form to a function and then call
  8.  * 'ReSize(Sender)' from within that function.
  9.  *
  10.  * It is a GOOD IDEA in your 'OnSized' event for the form to watch
  11.  * for resizing that is too small. If you resize the form too small
  12.  * you can cause this Resizer to crash your program. All you have to
  13.  * do is check the bounds of the form being resized, if they are less
  14.  * than a certain amount, set the bounds to the certain amount.
  15.  *
  16.  * See the example program for help or you can mail me:
  17.  *   mental@murdrum.nmsu.edu
  18.  *
  19.  * Obvious extensions are adding support to any container controls I
  20.  * may have missed. You can tell if something is a container control
  21.  * by placing another control on it and then try to move the control
  22.  * outside of it. If you cannot move the inner control outside, it
  23.  * IS a container control.
  24.  * I have NOT figured out how controls are stored on a TTabbedNotebook,
  25.  * (but honently I have not looked very hard, yet) so while the
  26.  * TTabbedNotebook will resize itself, the obejcts on the pages will
  27.  * not size themselvess.
  28.  *}
  29.  
  30. unit Resizer;
  31.  
  32. interface
  33.  
  34. uses
  35.   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  36.   Forms, Dialogs, ExtCtrls, StdCtrls, TabNotBk;
  37.  
  38. type
  39.   pControlInfo = ^tControlInfo;
  40.   tControlInfo = record
  41.      { This record holds information about a component on the form}
  42.      { or about a component inside a container object}
  43.      Obj:TControl;
  44.      ClassName:String;
  45.      lRatio,tRatio,wRatio,hRatio:Real;
  46.      Contains:pControlInfo;
  47.      Next:pControlInfo;
  48.   End;
  49.   TResizer = class(TComponent)
  50.   private
  51.     { These variables and functions should not be needed by the user, }
  52.     { only by the RESIZER component.}
  53.      ResizerInitialized:Boolean;
  54.      Function  GetClientControlCount(Sender:TObject):LongInt;
  55.      procedure GetNewWidthHeight(Sender:TObject;Var NewW,NewH:LongInt);
  56.      Procedure PerformResize(CurCont:pControlInfo;CWidth,CHeight:LongInt);
  57.      Function  GetClientControlObject(Sender:TObject;Index:LongInt):TControl;
  58.      Function  Initialize(Sender:TObject;CWidth,CHeight:LongInt):pControlInfo;
  59.      Procedure DeleteControlList(CurCont:pControlInfo);
  60.   public
  61.     constructor Create(AOwner: TComponent); override;
  62.     destructor  Destroy; override;
  63.     { These are useful to the programmer. I currently dont use NewShapshot, but}
  64.     { somebody out there might.... especially if you are using DYNAMICALLY}
  65.     { created components on your form.}
  66.     procedure   ReSize(ParentForm:TObject);
  67.     procedure   NewSnapshot(ParentForm:TObject);
  68.   end;
  69.  
  70. procedure Register;
  71.  
  72. implementation
  73.  
  74. Var ControlList:pControlInfo;
  75.  
  76. constructor TResizer.Create(AOwner: TComponent);
  77. Var Count:LongInt;
  78. Begin
  79.    inherited Create(AOwner);
  80.    { Do my init stuff}
  81.    ResizerInitialized:=False;
  82.    ControlList:=nil;
  83. End;
  84.  
  85. destructor TResizer.Destroy;
  86. Begin
  87.    { Destroy the existing ControlList }
  88.    DeleteControlList(ControlList);
  89.    ResizerInitialized:=False;
  90.    ControlList:=nil;
  91.    inherited Destroy;
  92. End;
  93.  
  94. { Recursively setup throw the control list and all containers}
  95. { and delete all the dynamically allocated objects}
  96. Procedure TResizer.DeleteControlList(CurCont:pControlInfo);
  97. Var NextCont:pControlInfo;
  98. Begin
  99.    While(CurCont<>nil) Do
  100.    Begin
  101.       If((CurCont^.Contains)<>nil) Then
  102.          DeleteControlList(CurCont^.Contains);
  103.       NextCont:=CurCont^.Next;
  104.       FreeMem(CurCont,SizeOf(tControlInfo));
  105.       CurCont:=NextCont;
  106.    End;
  107. End;
  108.  
  109. procedure TResizer.GetNewWidthHeight(Sender:TObject;Var NewW,NewH:LongInt);
  110. Begin
  111.    { Determine the type of container component we have then get its}
  112.    { width and height and tag number}
  113.    If(Sender is TForm) Then
  114.    With TForm(Sender) Do
  115.    Begin
  116.       { Since this is a TForm, we want ClientWidth and ClientHeight}
  117.       NewW:=ClientWidth;
  118.       NewH:=ClientHeight;
  119.    End
  120.    Else
  121.    If(Sender is TPanel) Then
  122.    With TPanel(Sender) Do
  123.    Begin
  124.       NewW:=Width;
  125.       NewH:=Height;
  126.    End
  127.    Else
  128.    If(Sender is TGroupBox) Then
  129.    With TGroupBox(Sender) Do
  130.    Begin
  131.       NewW:=Width;
  132.       NewH:=Height;
  133.    End
  134.    Else
  135.    {The TTabbedNotebook stuff doesn't work right... Components inside}
  136.    {the tabbed notebook won't resize as of yet}
  137.    If(Sender is TTabbedNotebook) Then
  138.    With TTabbedNotebook(Sender) Do
  139.    Begin
  140.       NewW:=Width;
  141.       NewH:=Height;
  142.    End
  143.    Else
  144.    Begin
  145.       { We don't recognize the container, so supply 0 values}
  146.       NewW:=0;
  147.       NewH:=0;
  148.    End;
  149. End;
  150.  
  151. Function TResizer.GetClientControlCount(Sender:TObject):LongInt;
  152. Begin
  153.    { Determine the type of container component we have then}
  154.    { return the number of controls on that container}
  155.    If(Sender is TForm) Then
  156.       Result:=TForm(Sender).ControlCount
  157.    Else
  158.    If(Sender is TPanel) Then
  159.       Result:=TPanel(Sender).ControlCount
  160.    Else
  161.    If(Sender is TGroupBox) Then
  162.       Result:=TGroupBox(Sender).ControlCount
  163.    Else
  164.    {The TTabbedNotebook stuff doesn't work right... Components inside}
  165.    {the tabbed notebook won't resize as of yet}
  166.    If(Sender is TTabbedNotebook) Then
  167.       Result:=TTabbedNotebook(Sender).ControlCount
  168.    Else
  169.       { We don't recognize the container, so supply a 0 value}
  170.       Result:=0;
  171. End;
  172.  
  173.  
  174. Function TResizer.GetClientControlObject(Sender:TObject;Index:LongInt):TControl;
  175. Begin
  176.    If(Sender is TForm) Then
  177.       Result:=TForm(Sender).Controls[Index]
  178.    Else
  179.    If(Sender is TPanel) Then
  180.       Result:=TPanel(Sender).Controls[Index]
  181.    Else
  182.    If(Sender is TGroupBox) Then
  183.       Result:=TGroupBox(Sender).Controls[Index]
  184.    Else
  185.    {The TTabbedNotebook stuff doesn't work right... Components inside}
  186.    {the tabbed notebook won't resize as of yet}
  187.    If(Sender is TTabbedNotebook) Then
  188.       Result:=TTabbedNotebook(Sender).Controls[Index]
  189.    Else
  190.       Result:=nil;
  191. End;
  192.  
  193. Function TResizer.Initialize(Sender:TObject;CWidth,CHeight:LongInt):pControlInfo;
  194. Var Temp:pControlInfo;
  195.     Count:Integer;
  196. Begin
  197.    Result:=nil;
  198.    For Count:=0 to (GetClientControlCount(Sender)-1) Do
  199.    Begin
  200.       GetMem(Temp,SizeOf(tControlInfo));
  201.       Temp^.Obj:=GetClientControlObject(Sender,Count);
  202.       With(Temp^) Do
  203.       Begin
  204.          lRatio:=(Obj.Left) / CWidth;
  205.          tRatio:=(Obj.Top) / CHeight;
  206.          wRatio:=(Obj.Width) / CWidth;
  207.          hRatio:=(Obj.Height) / CHeight;
  208.          Contains:=nil;
  209.          Next:=Result;
  210.       End;
  211.       Result:=Temp;
  212.       {The TTabbedNotebook stuff doesn't work right... Components inside}
  213.       {the tabbed notebook won't resize as of yet}
  214.       If((Temp^.Obj is TForm) or
  215.          (Temp^.Obj is TPanel) or
  216.          (Temp^.Obj is TGroupBox) or
  217.          (Temp^.Obj is TTabbedNotebook)) Then
  218.       With(Temp^) Do
  219.          Contains:=Initialize(Obj,Obj.Width,Obj.Height);
  220.    End;
  221. End;
  222.  
  223. Procedure TResizer.PerformResize(CurCont:pControlInfo;CWidth,CHeight:LongInt);
  224. Begin
  225.    While(CurCont<>nil) Do
  226.    Begin
  227.       With(CurCont^) Do
  228.       Begin
  229.          With(Obj) Do
  230.             SetBounds(Round(lRatio*CWidth),Round(tRatio*CHeight),
  231.                Round(wRatio*CWidth),Round(hRatio*CHeight));
  232.          If(Contains<>nil) Then
  233.             PerformResize(Contains,Obj.Width,Obj.Height);
  234.       End;
  235.       CurCont:=CurCont^.Next;
  236.    End;
  237. End;
  238.  
  239. procedure TResizer.NewSnapshot(ParentForm:TObject);
  240. Var NewClientWidth,NewClientHeight:LongInt;
  241. Begin
  242.    GetNewWidthHeight(ParentForm,NewClientWidth,NewClientHeight);
  243.    { Delete the existing ControlList for this form}
  244.    DeleteControlList(ControlList);
  245.    ControlList:=nil;
  246.    ResizerInitialized:=False;
  247.    { Initialize the ControlList for this form}
  248.    ControlList:=Initialize(ParentForm,NewClientWidth,NewClientHeight);
  249.    If(ControlList<>nil) Then
  250.       { The control list HAS been initialized!}
  251.       ResizerInitialized:=True;
  252. End;
  253.  
  254. { This should be called everytime the form is resized (ie in the OnSized}
  255. { event). Pass OnSized "Sender" parameter to this procedure}
  256. procedure TResizer.ReSize(ParentForm:TObject);
  257. Var NewClientWidth,NewClientHeight:LongInt;
  258.     Count:Integer;
  259.     Left,Top,Width,Height:LongInt;
  260. Begin
  261.    GetNewWidthHeight(ParentForm,NewClientWidth,NewClientHeight);
  262.    If(ResizerInitialized) Then
  263.       { The ControlList already exists, resize the form and its controls}
  264.       PerformResize(ControlList,NewClientWidth,NewClientHeight)
  265.    Else
  266.       { No ControlList exists. Let's create one}
  267.       NewSnapshot(ParentForm);
  268. End;
  269.  
  270. { This should be called only if you want to take a NEW shapshot of the}
  271. { relative positions and sizes of the controls on the form. The paramter}
  272. { should be the form on which the object resides}
  273. procedure Register;
  274. begin
  275.    { Register the RESIZER component}
  276.    RegisterComponents('New VCs', [TResizer]);
  277. end;
  278.  
  279. end.
  280.  
  281.